package com.ark.frigate.redis.lock.aspect;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;

import com.ark.frigate.redis.RedisLockService;
import com.ark.frigate.redis.lock.ManageAspect;
import com.ark.frigate.redis.lock.annotaion.CacheManage;
import com.ark.frigate.redis.utils.Base64Serializer;

import lombok.extern.slf4j.Slf4j;

/**
 * 缓存Aop
 *
 * @author zengweilong
 */
@Slf4j
@Aspect
public class CacheManageAspect extends ManageAspect {

    @Autowired
    private RedisLockService redisLockService;

    @Around("@annotation(cacheManage)")
    public Object executeBefore(ProceedingJoinPoint pjp, CacheManage cacheManage) throws Throwable {

        CacheResult cacheResult = new CacheResult();
        cacheResult.setCacheManage(cacheManage);
        cacheResult.setCacheKey(getCacheKey(pjp, cacheManage));
        log.info("redis key:{}", cacheResult.getCacheKey());
        //获取数据 优先从cache中获取
        String result = redisLockService.get(cacheResult.getCacheKey());
        if (StringUtils.isNotBlank(result)) {
            Signature signature = pjp.getSignature();
            Class clazz = ((MethodSignature) signature).getReturnType();
            return Base64Serializer.deserialize(result);
        }

        //缓存为空
        Object value = pjp.proceed();
        //当返回值不为Null时 设置缓存
        if (!Objects.isNull(value)) {
            setCache(value, cacheResult);
        }
        return value;
    }

    private String getCacheKey(ProceedingJoinPoint pjp, CacheManage cacheManage) {

        String cacheKey = cacheManage.key();

        Object[] objects = pjp.getArgs();
        if (objects != null) {
            int[] args = cacheManage.args();
            cacheKey += getKey(objects, args);
        }

        //拼key
        if (StringUtils.isBlank(cacheManage.key())) {
            cacheKey = getKey("CACHE:", pjp, cacheKey);
        } else {
            cacheKey = "CACHE:" + cacheKey;
        }
        return cacheKey;
    }

    private CacheResult setCache(Object value, CacheResult cacheResult) {

        if (!Objects.isNull(value)) {
            String result = Base64Serializer.serialize(value);
            //设置缓存 及有效时间
            redisLockService.set(cacheResult.getCacheKey(), result, cacheResult.getCacheManage().timeout());
        }

        return cacheResult;
    }

    class CacheResult {

        private CacheManage cacheManage;

        private String cacheKey = "";

        public CacheManage getCacheManage() {
            return cacheManage;
        }

        public void setCacheManage(CacheManage cacheManage) {
            this.cacheManage = cacheManage;
        }

        public String getCacheKey() {
            return cacheKey;
        }

        public void setCacheKey(String cacheKey) {
            this.cacheKey = cacheKey;
        }

    }
}
